package design.pattern.Lu06ProxyPattern;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @program JavaBase
 * @description: 动态代理
 *  - 被代理类必须实现一个接口
 * @author: zhanglu
 * @create: 2020-03-29 15:51:00
 */
public class Lu06ProxyPattern03 {

    public static void main(String[] args) throws Exception{

        IGamePlayer03 iGamePlayer03 = new GamePlayer03("张三");
//
//        Class<? extends IGamePlayer03> aClass = iGamePlayer03.getClass();
//        Constructor<?> constructor = aClass.getConstructor(String.class);
//
//        IGamePlayer03 o = (IGamePlayer03) constructor.newInstance(new Object[]{"张三"});
//        o.upgrade();
//
//
//        System.out.println(1);

        InvocationHandler handler = new GamePlayerProxy03(iGamePlayer03);

        IGamePlayer03 gamePlayer03 = (IGamePlayer03) Proxy.newProxyInstance(iGamePlayer03.getClass().getClassLoader(), new Class[]{IGamePlayer03.class}, handler);

        gamePlayer03.login("zhangsan", "111111");
        gamePlayer03.killBoss();
        gamePlayer03.upgrade();


    }

}

interface IGamePlayer03{

    void login(String username, String password);

    void killBoss();

    void upgrade();

}

class GamePlayer03 implements IGamePlayer03{

    private String name;

    public GamePlayer03(String name){
        this.name = name;
    }

    @Override
    public void login(String username, String password) {
        System.out.println("登陆：" + this.name + " - " + username + " - " + password);
    }

    @Override
    public void killBoss() {
        System.out.println("杀怪：" + this.name);
    }

    @Override
    public void upgrade() {
        System.out.println("升级：" + this.name);
    }
}

class GamePlayerProxy03 implements InvocationHandler{

    private Object object;

    public GamePlayerProxy03(Object o){
        this.object = o;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        Object invoke = method.invoke(this.object, args);

        return invoke;
    }

}

